<template>
  <div class="swiper" ref="swiper">
    <div
      class="swiper-track"
      :style="{
        transitionDuration,
        transform: `translateX(${translateX})`,
        width: trackWidth,
      }"
      @touchstart="onTouchStart"
      @touchmove="onTouchMove"
      @touchend="onTouchEnd"
      @touchcancel="onTouchEnd"
    >
      <div
        class="swiper-item"
        v-for="(item, i) in list"
        :key="i"
        :style="{
          width: swiperWidth + 'px',
          transform: firstOffsetX(i),
        }"
      >
        <img :src="item.url" />
      </div>
    </div>

    <div class="indicator">
      <div
        class="item"
        :class="{ active: i === index }"
        v-for="(item, i) in list"
        :key="i"
        @click="change(i)"
      ></div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Swiper",
  props: {
    list: {
      type: Array,
    },
    autoplay: {
      type: Number,
      default: 1500,
    },
    duration: {
      type: [Number, String],
      default: 500,
    },
  },
  watch: {
    index() {
      this.translate();
    },
  },
  computed: {
    // Swiper 轨道宽度
    trackWidth() {
      return `${this.list.length * this.swiperWidth}px`;
    },
    // 第一个元素移动到最后进行补位
    firstOffsetX() {
      return (itemIndex) => {
        let { index, count, trackWidth } = this;
        if (itemIndex === 0 && index === 0 && count > 0) {
          return `translateX(${trackWidth})`;
        }
        return "";
      };
    },
  },
  data() {
    return {
      count: 0,
      index: 0,
      timer: null,
      swiperWidth: "",
      swiperHeight: "",
      translateX: "0px",
      transitionDuration: "500ms",
      touchX: 0, // 滑动初始top位置
      elX: 0, // 元素最终top位置
      touchMax: 50, // 最大拖拽值
    };
  },
  mounted() {
    this.init();
    this.onResize();
  },
  destroyed() {
    this.autoStop();
  },
  methods: {
    init() {
      let { clientWidth, clientHeight } = this.$refs.swiper;
      this.swiperWidth = clientWidth;
      this.swiperHeight = clientHeight;
      this.autoStart();
    },
    onResize() {
      let _this = this;
      window.onresize = function () {
        _this.init();
      };
    },
    translate() {
      let { index, count, swiperWidth, trackWidth } = this;
      let tx = "0px";

      if (count > 0 && index === 0) {
        tx = `-${trackWidth}`;
      } else if (count > 0 && index === 1) {
        tx = `0px`;
        this.setJoinItem();
      } else {
        let left = -index * swiperWidth + "px";
        tx = `${left}`;
      }
      this.translateX = tx;
    },
    setJoinItem() {
      this.transitionDuration = "0ms";
      setTimeout(() => {
        this.transitionDuration = "500ms";
        this.translateX = `-${this.swiperWidth}px`;
      }, 5);
    },
    // 自动切换
    autoStart() {
      if (this.timer) {
        return;
      }
      this.timer = setInterval(() => {
        this.index = (this.index + 1) % this.list.length;

        this.count++;
      }, this.autoplay);
    },
    autoStop() {
      clearInterval(this.timer);
      this.timer = null;
    },
    change(index) {
      this.index = index;
      this.autoStop();
      this.autoStart();
    },
    onTouchStart(e) {
      // 目标事件
      let touch = e.targetTouches[0];
      // 目标元素
      let el = e.target;
      // 记录目标元素原始位置
      this.touchX = touch.clientY - el.offsetTop;
    },
    onTouchMove(e) {
      let touch = e.targetTouches[0];
      let { clientX } = touch;
      let offsetX = clientX - this.touchX;

      if (offsetX < -this.touchMax) {
        console.log(0);
        offsetX = -this.touchMax;
      } else if (offsetX >= this.touchMax) {
        console.log(1);
        offsetX = this.touchMax;
      }

      // 减小一倍拖动阻力
      this.elX = offsetX * 2;
    },
    onTouchEnd() {
      if (this.elTop < -this.touchMax) {
        console.log(0);
        // this.onPrev();
      } else if (this.elTop > this.touchMax) {
        console.log(1);
        // this.onNext();
      }
      this.elTop = 0;
      // document.removeEventListener('touchmove', this.defaultEvent);
    },
    //阻止默认事件
    defaultEvent(e) {
      e.preventDefault();
    },
  },
};
</script>

<style lang="scss" scoped>
.swiper {
  height: 200px;
  margin: auto;
  position: relative;
  overflow: hidden;

  .swiper-track {
    height: 100%;

    .swiper-item {
      height: 100%;
      float: left;

      img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }
  }

  .indicator {
    position: absolute;
    left: 0px;
    right: 0;
    bottom: 8px;
    margin: auto;
    display: flex;
    align-items: center;
    justify-content: center;

    .item {
      width: 8px;
      height: 8px;
      background: #fff;
      border-radius: 50%;
      float: left;
      margin-right: 8px;
      cursor: pointer;

      &:last-of-type {
        margin-right: 0;
      }
    }

    .active {
      width: 30;
      height: 30;
      background: red;
    }
  }
}
</style>